home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Aminet 28
/
Aminet 28 (1998)(GTI - Schatztruhe)[!][Dec 1998].iso
/
Aminet
/
dev
/
lang
/
fpcsrc.lha
/
fpc
/
compiler
/
cga68k.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
1998-09-24
|
58KB
|
1,430 lines
{
$Id: cga68k.pas,v 1.2.2.7 1998/08/14 12:04:36 carl Exp $
Copyright (c) 1993-98 by Florian Klaempfl, Carl Eric Codere
This unit generates 68000 (or better) assembler from the parse tree
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
****************************************************************************
}
unit cga68k;
interface
uses
objects,cobjects,verbose,systems,globals,tree,symtable,types,strings,
pass_1,hcodegen,aasm,m68k,tgen68k,files,gdb;
procedure emitl(op : tasmop;var l : plabel);
procedure emit_reg_reg(i : tasmop;s : topsize;reg1,reg2 : tregister);
procedure emitcall(const routine:string;add_to_externals : boolean);
procedure emitloadord2reg(location:Tlocation;orddef:Porddef;
destreg:Tregister;delloc:boolean);
{ produces jumps to true respectively false labels using boolean expressions }
procedure maketojumpbool(p : ptree);
procedure emitoverflowcheck(p: ptree);
procedure push_int(l : longint);
function maybe_push(needed : byte;p : ptree) : boolean;
procedure restore(p : ptree);
procedure emit_push_mem(const ref : treference);
procedure emitpushreferenceaddr(const ref : treference);
procedure swaptree(p: ptree);
procedure copystring(const dref,sref : treference;len : byte);
procedure concatcopy(source,dest : treference;size : longint;delsource : boolean);
{ see implementation }
procedure maybe_loada5;
procedure emit_bounds_check(hp: treference; index: tregister);
procedure loadstring(p:ptree);
procedure floatload(t : tfloattype;const ref : treference; var location:tlocation);
{ return a float op_size from a floatb type }
{ also does some error checking for problems }
function getfloatsize(t: tfloattype): topsize;
procedure floatstore(t : tfloattype;var location:tlocation; const ref:treference);
{ procedure floatloadops(t : tfloattype;var op : tasmop;var s : topsize);
procedure floatstoreops(t : tfloattype;var op : tasmop;var s : topsize); }
procedure firstcomplex(p : ptree);
procedure secondfuncret(var p : ptree);
{ initialize respectively terminates the code generator }
{ for a new module or procedure }
procedure codegen_doneprocedure;
procedure codegen_donemodule;
procedure codegen_newmodule;
procedure codegen_newprocedure;
{ generate entry code for a procedure.}
procedure genentrycode(const proc_names:Tstringcontainer;make_global:boolean;
stackframe:longint;
var parasize:longint;var nostackframe:boolean);
{ generate the exit code for a procedure. }
procedure genexitcode(parasize:longint;nostackframe:boolean);
implementation
{
procedure genconstadd(size : topsize;l : longint;const str : string);
begin
if l=0 then
else if l=1 then
exprasmlist^.concat(new(pai68k,op_A_INC,size,str)
else if l=-1 then
exprasmlist^.concat(new(pai68k,op_A_INC,size,str)
else
exprasmlist^.concat(new(pai68k,op_ADD,size,'$'+tostr(l)+','+str);
end;
}
procedure copystring(const dref,sref : treference;len : byte);
var
pushed : tpushed;
begin
pushusedregisters(pushed,$ffff);
{ emitpushreferenceaddr(dref); }
{ emitpushreferenceaddr(sref); }
{ push_int(len); }
{ This speeds up from 116 cycles to 24 cycles on the 68000 }
{ when passing register parameters! }
exprasmlist^.concat(new(pai68k,op_ref_reg(A_LEA,S_L,newreference(dref),R_A1)));
exprasmlist^.concat(new(pai68k,op_ref_reg(A_LEA,S_L,newreference(sref),R_A0)));
exprasmlist^.concat(new(pai68k,op_const_reg(A_MOVE,S_L,len,R_D0)));
emitcall('STRCOPY',true);
maybe_loada5;
popusedregisters(pushed);
end;
procedure loadstring(p:ptree);
begin
case p^.right^.resulttype^.deftype of
stringdef : begin
{ load a string ... }
{ here two possible choices: }
{ if it is a char, then simply }
{ load 0 length string }
if (p^.right^.treetype=stringconstn) and
(p^.right^.values^='') then
exprasmlist^.concat(new(pai68k,op_const_ref(
A_MOVE,S_B,0,newreference(p^.left^.location.reference))))
else
copystring(p^.left^.location.reference,p^.right^.location.reference,
min(pstringdef(p^.right^.resulttype)^.len,pstringdef(p^.left^.resulttype)^.len));
end;
orddef : begin
if p^.right^.treetype=ordconstn then
begin
{ offset 0: length of string }
{ offset 1: character }
exprasmlist^.concat(new(pai68k,op_const_ref(A_MOVE,S_W,1*256+p^.right^.value,
newreference(p^.left^.location.reference))))
end
else
begin
{ not so elegant (goes better with extra register }
if (p^.right^.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
begin
exprasmlist^.concat(new(pai68k,op_reg_reg(
A_MOVE,S_B,p^.right^.location.register,R_D0)));
ungetregister32(p^.right^.location.register);
end
else
begin
exprasmlist^.concat(new(pai68k,op_ref_reg(
A_MOVE,S_B,newreference(p^.right^.location.reference),R_D0)));
del_reference(p^.right^.location.reference);
end;
{ alignment can cause problems }
{ add length of string to ref }
exprasmlist^.concat(new(pai68k,op_const_ref(A_MOVE,S_B,1,
newreference(p^.left^.location.reference))));
(* if abs(p^.left^.location.reference.offset) >= 1 then
Begin *)
{ temporarily decrease offset }
Inc(p^.left^.location.reference.offset);
exprasmlist^.concat(new(pai68k,op_reg_ref(A_MOVE,S_B,R_D0,
newreference(p^.left^.location.reference))));
Dec(p^.left^.location.reference.offset);
{ restore offset }
(* end
else
Begin
Comment(V_Debug,'SecondChar2String() internal error.');
internalerror(34);
end; *)
end;
end;
else
Message(sym_e_type_mismatch);
end;
end;
procedure restore(p : ptree);
var
hregister : treg